package com.yonyou.gmcc.gateway.web.shiro;

import java.io.IOException;
import java.io.Serializable;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionContext;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.yonyou.gmcc.gateway.web.consts.CommonConstants;
import com.yonyou.gmcc.gateway.web.entity.UserEntity;
import com.yonyou.gmcc.gateway.web.util.CookieUtil;
import com.yonyou.gmcc.gateway.web.util.Md5Utils;
import com.yonyou.gmcc.gateway.web.util.ReflectionUtils;
import com.yonyou.gmcc.gateway.web.util.SpringUtil;

public class TokenDelegatingFilterProxy extends DelegatingFilterProxy{
	@Autowired
	@Qualifier("sessionManager")
	private SessionManager sessionManager;
	@Autowired
	@Qualifier("securityManager")
	private DefaultWebSecurityManager securityManager;
	
	private static final Logger log = LoggerFactory.getLogger(TokenDelegatingFilterProxy.class);
	
	public TokenDelegatingFilterProxy(String name){
		super(name);
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		HttpServletRequest req=(HttpServletRequest)request;
		log.info("---enter TokenDelegatingFilterProxy.doFilter,url="+req.getRequestURI());
		if(req.getRequestURI().contains("/unauthor")){
			((HttpServletResponse)response).setStatus(403);
			return;
		}

//        Object obj1=ReflectionUtils.getFieldValue(request, "request");
//		sessionManager=(SessionManager)SpringUtil.getBean("sessionManager");
//        WebSessionContext wsc = new DefaultWebSessionContext();
//        Session session=sessionManager.toCreateSession(wsc);
//        Serializable id=session.getId();
//        wsc.setServletRequest(request);
//        wsc.setServletResponse(response);
//        sessionManager.toStart(session, wsc);
//        Cookie cookie=new Cookie("JSESSIONID",id.toString());
//        cookie.setDomain("/");
//        Cookie[] cookies=new Cookie[]{cookie};
//        ReflectionUtils.setFieldValue(obj1, "cookies", cookies);
		UserEntity user=CookieUtil.getHeadUserInfo(req);
		if(user!=null){
			UsernamePasswordToken upt = new UsernamePasswordToken(user.getUserId(), Md5Utils.getMD5(CommonConstants.COMMON_PASSWORD));
			upt.setHost("web");
			securityManager=(DefaultWebSecurityManager)SpringUtil.getBean("securityManager");
			SecurityUtils.setSecurityManager(securityManager);
			Subject subject = new Subject.Builder().buildSubject();//SecurityUtils.getSubject();
			ThreadContext.bind(subject);
			try {
				//sessionManager=(SessionManager)SpringUtil.getBean("sessionManager");
				//sessionManager.validateSessions();

				subject.login(upt);
				Session session=subject.getSession();
		        Serializable id=session.getId();
				log.info("---enter TokenDelegatingFilterProxy.doFilter,sessionid="+id);
		        Cookie sessioncookie=new Cookie(CommonConstants.COOKIE_NAME,id.toString());
		        sessioncookie.setDomain("/");
		        
		        Cookie[] olds=req.getCookies();
		        Cookie[] cookies=new Cookie[2];
		        cookies[0]=sessioncookie;
		        
		        Cookie usercookie=new Cookie(CommonConstants.USER_COOKIE_NAME,req.getHeader(CommonConstants.USER_HEADER_NAME));
		        usercookie.setDomain("/");
		        cookies[1]=usercookie;
//		        for(int i=0;i<olds.length;i++){
//		        	cookies[i+1]=olds[i];
//		        }
		        Object obj1=ReflectionUtils.getFieldValue(request, "request");
		        ReflectionUtils.setFieldValue(obj1, "cookies", cookies);
			} catch (AuthenticationException e) {
				e.printStackTrace();
			}
		}
		super.doFilter(request, response, filterChain);
	}
}
